<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    
  </style>
</head>
<body>
  
</body>
<script>
  
  // 元素

  // 绑定：a事件，fn1
  // 绑定：a事件，fn2
  // 绑定：a事件，fn3

  // 解绑：a事件，fn2

  // 发布了a动作，执行fn1，fn3


  var ele = {
    name:"div",
    className:"box",
    event:{
      // a:[f1, f2],
      // b:[f3, f4],
      // c:[f5]
    },
    add:function(type, cb){
      // 根据传入的事件类型，判断对象中是否存在
      if(this.event[type]){
        // 存在，添加事件处理函数
        this.event[type].push(cb)
      }else{
        // 不存在，直接添加该属性，值为数组，内是当前事件处理函数
        this.event[type] = [cb];
      }
    },
    remove:function(type, cb){
      // 判断对象中是否存在该事件类型，不存在，结束
      if( !this.event[type] ) return;
      // 遍历当前类型对应属性的所有事件处理函数
      // for(var i=0;i<this.event[type].length;i++){
      //   // 和传入的事件处理函数比对
      //   if(this.event[type][i] === cb){
      //     // 找到重复的结束，此时的i就是重复的事件处理函数的索引
      //     break;
      //   }
      // }
      // =====
      var i=0;
      var flag = this.event[type].some(function(val,idx){
        i = idx;
        return val === cb;
      })
      if(!flag) return;
      // =====

      // 根据找到的这个索引，删除数组中的数据
      this.event[type].splice(i, 1);
    },
    emit:function(type){
      // 判断对象中是否存在该事件类型，不存在，结束
      if( !this.event[type] ) return;
      // 遍历当前类型对应属性的所有事件处理函数
      this.event[type].forEach(function(val){
        // 执行事件处理函数
        val();
      })
    }
  };


  ele.add("a", f1);
  ele.add("a", f2);
  ele.add("b", f3);
  ele.add("b", f4);
  ele.add("c", f5);

  console.log(ele)

  // ele.remove("q", f1)
  // ele.remove("c", f5)
  // ele.remove("a", f1)

  ele.emit("a");    // 
  ele.emit("b");    // 
  // ele.emit("c");    //
  // ele.emit("q");    //




  function f1(){
    console.log("1")
  }
  function f2(){
    console.log("2")
  }
  function f3(){
    console.log("3")
  }
  function f4(){
    console.log("4")
  }
  function f5(){
    console.log("5")
  }
</script>
</html>